package com.suneee.trades.dao.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.suneee.base.util.ContextHelper;
import com.suneee.context.page.Page;
import com.suneee.context.page.Sort;
import com.suneee.context.page.Sort.Order;
import com.suneee.core.util.StringUtils;
import com.suneee.orm.GenericDao;
import com.suneee.orm.util.WhereClauseBuilder;
import com.suneee.trades.bean.TradesInfoDTO;
import com.suneee.trades.dao.TradesInfoDao;
import com.suneee.trades.entity.HistoryOrder;
import com.suneee.trades.entity.TradesInfo;
import com.suneee.trades.resource.OfflineStatus;
import com.suneee.trades.resource.OrderStatus;
import com.suneee.trades.resource.SplitStatus;
import com.suneee.trades.resource.TradesStatus;

@Repository("tradesInfoDao")
public class TradesInfoDaoImpl extends GenericDao<TradesInfo, String>implements TradesInfoDao {

	@Override
	public void batchUpdateTradesInfo(List<TradesInfo> infos) {
		this.update(infos);
	}

	@Override
	public List<TradesInfo> batchTradesInfoByTid(List<Object> args) {
		WhereClauseBuilder wcb = new WhereClauseBuilder();
		wcb.in("tid", args);
		return this.selectWhere(wcb.getSql(), wcb.getArgs());
	}

	@Override
	public boolean isLocked(String[] tids,Integer adminId) {
		WhereClauseBuilder wcb = new WhereClauseBuilder(" select * from t_trades_info where 1=1 ");
		List<Object> args = new ArrayList<>();
		Collections.addAll(args, tids);
		wcb.equals("is_locked", 1);
		wcb.noEquals("locked", adminId);
		wcb.in("tid", args);
		List<TradesInfo> list = this.executeQuery(wcb.getSql(), wcb.getArgs());
		return null != list && list.size() > 0;
	}

	@Override
	public TradesInfo getTradesInfo(String tid) {
		return this.select(tid);
	}

	/*
	 * @Override public List<TradesInfo> getExaminList(TradesInfoDTO dto) {
	 * StringBuffer sql = new StringBuffer(); sql.append(" 1=1"); List<Object>
	 * args = new ArrayList<>(); if(dto.getShopId() != null){ sql.append(
	 * " and shop_id=?"); args.add(dto.getShopId()); }
	 * if(!StringUtils.isEmpty(dto.getRemark())){ sql.append(
	 * " and remark like ?"); args.add("%"+dto.getRemark()+"%"); }
	 * if(!StringUtils.isEmpty(dto.getTid())){ sql.append(" and tid=?");
	 * args.add(dto.getTid()); } if(!StringUtils.isEmpty(dto.getBuyerNick())){
	 * sql.append(" and buyer_nick=?"); args.add(dto.getBuyerNick()); }
	 * if(dto.getStartCreatedTime() != null){ sql.append(
	 * " and DATE_FORMAT(created, '%Y-%m-%d %H:%i:%S') >=");
	 * args.add("DATE_FORMAT('"+DateUtils.formatDateTime(dto.getStartCreatedTime
	 * ())+"', '%Y-%m-%d %H:%i:%S')"); } if(dto.getEndCreatedTime() != null){
	 * sql.append(" and DATE_FORMAT(created, '%Y-%m-%d %H:%i:%S') <=");
	 * args.add("DATE_FORMAT('"+DateUtils.formatDateTime(dto.getEndCreatedTime()
	 * )+"', '%Y-%m-%d %H:%i:%S')"); }
	 * if(!StringUtils.isEmpty(dto.getOfflineStatus())){ sql.append(
	 * " and offline_status=?"); args.add(dto.getOfflineStatus()); }
	 * List<TradesInfo> list = this.selectWhere(sql.toString(),args);
	 * 
	 * return list; }
	 */

	@Override
	public Page<Map<String, Object>> getExaminPageList(TradesInfoDTO dto) 
	{
		List<Object> list = null;
		Integer adminId = ContextHelper.getCurrentLoginInfo().getAdminId();
		List<Map<String,Object>> shopList = this.queryForList("select shop_id from t_shop_admin where admin_id = ?", adminId);
		if(null != shopList && shopList.size() > 0)
		{
			list = new ArrayList<Object>();
			for(Map<String,Object> map :shopList)
			{
				list.add(map.get("shop_id"));
			}	
		}
		if(null == shopList || shopList.size() == 0)
		{
			list = new ArrayList<Object>();
			list.add(" ");
		}
		StringBuffer sql = new StringBuffer("select t.buyer_memo as buyerMemo, t.merge_tids as mergeTids, t.tid,t.created,t.buyer_nick as buyerNick,t.buyer_message as buyerMessage,t.timeout_action_time as timeoutActionTime,t.payment,t.remark,t.offline_status as offlineStatus,t.split_status as splitStatus,t.merge_status as mergeStatus, s.name as shopName,cha.`name` as channelName from t_trades_info t LEFT JOIN t_shop s on s.shop_id = t.shop_id and t.enterprise_code = s.enterprise_code LEFT JOIN t_channel cha on cha.channel_code = s.channel_code where t.tid NOT IN (SELECT tid FROM t_refund_apply WHERE process_status = 'INIT' OR process_status = 'PROCESS') AND ");
		
		WhereClauseBuilder sbf = new WhereClauseBuilder();
		sbf.equals("t.shop_id", dto.getShopId());
		sbf.in("t.shop_id", list);
		sbf.contains("t.remark", dto.getRemark());
		sbf.equals("t.tid", dto.getTid());
		sbf.contains("t.buyer_nick", dto.getBuyerNick());
		sbf.noEquals("t.split_status", SplitStatus.SPLIT_ACHIEVE.name());
		sbf.noEquals("t.split_status", null);
		List<Object> offList = new ArrayList<Object>();
		offList.add(OfflineStatus.ARRANGE_ORDER.name());
		offList.add(OfflineStatus.REVIEW_ORDER.name());
		offList.add(OfflineStatus.DELAYED_DELIVERY.name());
		offList.add(OfflineStatus.RE_ORDER.name());
		sbf.in("t.offline_status", offList);
		sbf.equals("t.enterprise_code",dto.getEnterpriseCode());
		
		//dto.setOfflineStatus(OfflineStatus.REVIEW_ORDER.toString());
		sbf.between("t.created", dto.getCreateStartTime(), dto.getCreateEndTime());
		sbf.equals("cha.channel_code",dto.getChannelCode());
		sql.append(sbf.getSql());
		dto.setSort((dto.getSort() == null || StringUtils.isEmpty(dto.getSort().getOrderByClause())) ? new Sort("t.created", Order.DESC) : dto.getSort());
		return this.queryForList(sql.toString(), dto, sbf.getArgs());
	}

//	@Override
//	public Page<TradesInfo> historyOrders(TradesInfoDTO dto) {
//		WhereClauseBuilder wcb = buildSql(dto);
//		Page<TradesInfo> page = this.executeQuery(wcb.getSql(), dto, wcb.getArgs());
//		return page;
//	}
	
	@Override
	public Page<Map<String, Object>> historyOrders(TradesInfoDTO dto) {
		WhereClauseBuilder wcb = buildSql(dto);
		return this.queryForList(wcb.getSql(), dto, wcb.getArgs());
	}

	private WhereClauseBuilder buildSql(TradesInfoDTO dto) {
		List<Object> list = null;
		Integer adminId = ContextHelper.getCurrentLoginInfo().getAdminId();
		List<Map<String,Object>> shopList = this.queryForList("select shop_id from t_shop_admin where admin_id = ?", adminId);
		if(null != shopList && shopList.size() > 0)
		{
			list = new ArrayList<Object>();
			for(Map<String,Object> map :shopList)
			{
				list.add(map.get("shop_id"));
			}
		}
		if(null == shopList || shopList.size() == 0)
		{
			list = new ArrayList<Object>();
			list.add(" ");
		}
		
//		WhereClauseBuilder wcb = new WhereClauseBuilder(
//				"select tti.*,sp.channel_code as channelCode, cl.`name` as channelName from t_trades_info as tti left join (select max(consign_time) as consign_time,tid from t_trades_order group by tid) as tto on tti.tid = tto.tid LEFT JOIN t_shop sp ON sp.shop_id = tti.shop_id LEFT JOIN t_channel cl ON cl.channel_code = sp.channel_code where 1 = 1 ");
		WhereClauseBuilder wcb = new WhereClauseBuilder("select tti.shop_id as shopId, tti.tid as tid,tti.pay_time as payTime,tti.buyer_nick as buyerNick,tti.buyer_message as buyerMessage,tti.remark as remark,sp.channel_code AS channelCode,cl.`name` AS channelName "
				+ " ,tti.created as created,tti.is_change_goods as isChangeGoods,tti.is_refund as isRefund,tti.is_refund_goods as isRefundGoods,tti.`status` as status "
				+ "  from t_trades_info as tti left join (select max(consign_time) as consign_time,tid from t_trades_order group by tid) as tto on tti.tid = tto.tid LEFT JOIN t_shop sp ON sp.shop_id = tti.shop_id LEFT JOIN t_channel cl ON cl.channel_code = sp.channel_code where 1 = 1 ");
		
		wcb.equals("tti.tid", dto.getTid());
		wcb.equals("tti.shop_id", dto.getShopId());
		wcb.in("tti.shop_id", list);
		wcb.equals("tti.buyer_nick", dto.getBuyerNick());
		wcb.equals("tti.enterprise_code",dto.getEnterpriseCode());
		wcb.equals("cl.channel_code",dto.getChannelCode());
		wcb.between("tti.pay_time", dto.getPayStartTime(), dto.getPayEndTime());//下单时间
		wcb.between("tti.audit_time", dto.getReviewStartTime(), dto.getReviewEndTime());//审单时间
		wcb.between("tto.consign_time", dto.getShoppStartTime(), dto.getShoppEndTime());
		
		String tradeType = dto.getTradeType();
		if (OrderStatus.TRADE_BUYER_SIGNED.name().equals(tradeType)) {
			List<Object> status = new ArrayList<>();
			status.add(TradesStatus.TRADE_BUYER_SIGNED);
			status.add(TradesStatus.TRADE_FINISHED);
			wcb.in("tti.status", status);
		} else if (OrderStatus.REFUND_GOODS.name().equals(tradeType)) {
			wcb.equals("tti.is_refund_goods", true);
		} else if (OrderStatus.CHANGE_GOODS.name().equals(tradeType)) {
			wcb.equals("tti.is_change_goods", true);
		} else if (OrderStatus.REFUND.name().equals(tradeType)) {
			wcb.equals("tti.is_refund", true);
		}else{
			List<Object> status = new ArrayList<>();
			status.add(TradesStatus.TRADE_BUYER_SIGNED);
			status.add(TradesStatus.TRADE_FINISHED);
			wcb.in("tti.status", status);
			wcb.append(" or tti.is_refund = ?", true);
			wcb.append(" or tti.is_refund_goods = ?", true);
			wcb.append(" or tti.is_change_goods = ?", true);
		}
		if (dto.getPayTimeSort() == 0) {
			dto.setSort((dto.getSort() == null || StringUtils.isEmpty(dto.getSort().getOrderByClause())) ? new Sort("tti.pay_time", Order.DESC) : dto.getSort());
		} else {
			dto.setSort((dto.getSort() == null || StringUtils.isEmpty(dto.getSort().getOrderByClause())) ? new Sort("tti.pay_time", Order.ASC) : dto.getSort());
		}
		return wcb;
	}
	
	

	@Override
	public List<TradesInfo> exportHistoryOrders(TradesInfoDTO dto) {
		WhereClauseBuilder wcb = buildSql(dto);
		List<TradesInfo> list = this.executeQuery(wcb.getSql(), wcb.getArgs());
		return list;
	}
	

	@Override
	public List<TradesInfo> getDoInTrade(String enterpriseCode) {
		List<Object> list = new ArrayList<Object>();
//		list.add(OfflineStatus.DELAYED_DELIVERY.name());
//		list.add(OfflineStatus.RE_ORDER.name());
		list.add(OfflineStatus.ARRANGE_ORDER.name());
		list.add(OfflineStatus.REVIEW_ORDER.name());
		list.add(OfflineStatus.DELAYED_DELIVERY.name());
		list.add(OfflineStatus.RE_ORDER.name());
		WhereClauseBuilder sbf = new WhereClauseBuilder();
		sbf.in("offline_status", list);
		sbf.noEquals("split_status", SplitStatus.SPLIT_ACHIEVE.name());
		sbf.noEquals("split_status", null);
		sbf.equals("enterprise_code",enterpriseCode);
		sbf.equals("status","WAIT_SELLER_SEND_GOODS");
		sbf.appendWhere( " tid NOT IN (SELECT DISTINCT a.tid FROM t_trades_info a INNER JOIN t_refund_apply b ON a.tid = b.tid  WHERE a.enterprise_code = '"+ enterpriseCode +"' AND (b.process_status = 'INIT' OR b.process_status = 'PROCESS')) ");
		return this.selectWhere(sbf.getSql(), sbf.getArgs());
	}

	@Override
	public List<Map<String, Object>> getTotalFree(String enterpriseCode) {
		WhereClauseBuilder sbf = new WhereClauseBuilder();
		return this.queryForList("select sum(total_fee) as totalFee from t_trades_info where enterprise_code='"+enterpriseCode+"'", sbf.getArgs());
	}

	@Override
	public List<TradesInfo> getDoInTradeSyn(String enterpriseCode) {
		List<Object> list = new ArrayList<Object>();
//		list.add(OfflineStatus.DELAYED_DELIVERY.name());
//		list.add(OfflineStatus.RE_ORDER.name());
		list.add(OfflineStatus.REVIEW_ORDER.name());
		list.add(OfflineStatus.ARRANGE_ORDER.name());
		
		List<Object> list1 = new ArrayList<Object>();
		list1.add(OfflineStatus.TRADE_FINISHED.name());
		list1.add(OfflineStatus.TRADE_CLOSED.name());
		list1.add(OfflineStatus.TRADE_CLOSED_BY_TAOBAO.name());
		list1.add(OfflineStatus.TRADE_BUYER_SIGNED.name());
		
		
		WhereClauseBuilder sbf = new WhereClauseBuilder();
		sbf.in("offline_status", list);
		sbf.equals("enterprise_code",enterpriseCode);
		
		return this.selectWhere(sbf.getSql(), sbf.getArgs());
	}

	@Override
	public List<TradesInfo> queryNotSynTradesInfo(String enterpriseCode) {
		Object[] args = new Object[2];
		args[0] = "1";
		args[1] = enterpriseCode;
		return this.selectWhere(" syn_status=? and enterprise_code=?", args);
	}

	@Override
	public boolean checkRefundId(String tid) 
	{
		if(StringUtils.isEmpty(tid))
		{
			return false;
		}
		List<Map<String,Object>> resultList = this.queryForList("SELECT DISTINCT a.tid FROM t_trades_info a INNER JOIN t_refund_apply b ON a.tid = b.tid  WHERE a.enterprise_code = 'a' AND (b.process_status = 'INIT' OR process_status = 'PROCESS') AND a.tid = ?", tid);
		boolean flag =  null != resultList && resultList.size() > 0;
		return flag;
	}


}
